//
//  XSChartView.m
//  Test
//
//  Created by xueshan1 on 2018/12/13.
//  Copyright © 2018 xueshan1. All rights reserved.
//

#import "XSChartView.h"
#import "XSChartTool.h"
#import "UIView+XSLayout.h"

static CGFloat ToAxisSpace = 5;

@interface XSChartView ()<CAAnimationDelegate>{
    CGPoint _originPoint;
    CGFloat _axisLabelHeight;
    CGFloat _chartViewDataHeight;
     
    CGFloat _yAxisMaxValue;
    CGFloat _xAxisMaxValue;
    CGFloat _yStepMargin;
    CGFloat _xStepMargin;
    
    CGFloat _pillarMargin;
}

@property(nonatomic,strong)NSArray<XSChartViewModel *> *dataSource;
@property(nonatomic,assign)CGFloat dataMaxValue;
@property(nonatomic,strong)NSMutableArray<CAShapeLayer *> *axisLayers;
@property(nonatomic,strong)NSMutableArray<CAShapeLayer *> *dataLabyers;
@property(nonatomic,strong)NSMutableArray *allSubViews;
@property(nonatomic,strong)NSMutableArray<UILabel *> *yAxisLabels;
@property(nonatomic,strong)NSMutableArray<UILabel *> *xAxisLabels;

//
@property(nonatomic,strong)UIScrollView *xScrollView;
@property(nonatomic,strong)UILabel *yAxisLabel;
@property(nonatomic,strong)UILabel *xAxisLabel;

@end

@implementation XSChartView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initData];
        
    }
    return self;
}

- (void)initData{
    _isShowGridding = YES;
    _leftMargin = 40;
    _topMargin = 40;
    _yAxisCount = 5;
    _axisFontSize = 14;
    _axisWidth = 1;
    _axisColor = [UIColor blackColor];
    _yStepMargin = _xStepMargin = 30;
    _lineWidth = 0.8;
    _pillarWidth = 20;
    _pillarMargin = 20;
    //
    _axisLabelHeight = 10;
    
    _axisLayers = [NSMutableArray array];
    _dataLabyers = [NSMutableArray array];
    _allSubViews = [NSMutableArray array];
    _yAxisLabels = [NSMutableArray array];
    _xAxisLabels = [NSMutableArray array];
}

- (UIScrollView *)xScrollView{
    if (!_xScrollView) {
        _xScrollView = [[UIScrollView alloc]init];
        _xScrollView.bounces = NO;
        _xScrollView.showsHorizontalScrollIndicator = NO;
        
    }
    return _xScrollView;
}


- (void)drawChartViewWithDataSource:(NSArray<XSChartViewModel *>*)dataSource{
    self.dataSource = dataSource;
    if (dataSource.count >0) {
        //y最大值
        _dataMaxValue = dataSource.firstObject.maxValue;
        for (XSChartViewModel *viewModel in dataSource) {
            if (_dataMaxValue < viewModel.maxValue) {
                _dataMaxValue = viewModel.maxValue;
            }
        }
    }else{
        return;
    }
    
    if (self.xAxisTitles.count == 0) {
        //x轴坐标
        NSMutableArray *xTitles = [NSMutableArray array];
        for (int i = 1; i<[[(self.dataSource.firstObject) dataSource]count] + 1; i++) {
            [xTitles addObject:[NSString stringWithFormat:@"%d",i]];
        }
        self.xAxisTitles = xTitles;
    }
    
    
    
    [self drawChartView];
    
}
- (void)drawChartView{
    
    _axisLabelHeight = [XSChartTool sizeWithText:@"x轴" fontSize:_axisFontSize].height;
    _chartViewDataHeight = self.height - _axisLabelHeight - _topMargin;
    _yAxisMaxValue = _topMargin/2;
    _originPoint = CGPointMake(_leftMargin, self.height - _axisLabelHeight);
    _yStepMargin = _chartViewDataHeight/_yAxisCount;
    
    if (self.chartType == XSChartViewType_Pillar) {
        _xStepMargin = _pillarWidth * self.dataSource.count + _pillarMargin;
    }
    
    [self drawYAxis];
    
    [self drawXAxis];
    
    if (self.chartType == XSChartViewType_Line) {
        
        [self drawYAxisSeperator];
        
        [self drawXAxisSeperator];
        
        [self drawChartViewPots];
        
        [self drawChartViewLines];
        
    }else{
        
        [self drawPillarView];
    }
    
    
    [self addAnimation:YES];
    
}
#pragma mark - 坐标轴
- (void)drawYAxis{
    
    UIBezierPath *yPath = [UIBezierPath bezierPath];
    [yPath moveToPoint:_originPoint];
    [yPath addLineToPoint:CGPointMake(_originPoint.x, _yAxisMaxValue)];
    [yPath addLineToPoint:CGPointMake(_leftMargin - (_axisWidth + ToAxisSpace), _yAxisMaxValue + ToAxisSpace)];
    [yPath moveToPoint:CGPointMake(_originPoint.x, _yAxisMaxValue)];
    [yPath addLineToPoint:CGPointMake(_leftMargin + (_axisWidth + ToAxisSpace), _yAxisMaxValue + ToAxisSpace)];
    CAShapeLayer *yLayer = [XSChartTool shapeLayerWithPath:yPath lineWidth:_axisWidth fillColor:[UIColor clearColor] strokeColor:_axisColor];
    [self.layer addSublayer:yLayer];
    [self.axisLayers addObject:yLayer];
    
    for (int i = 0; i<_yAxisCount + 1; i++) {
        NSString *title = [NSString stringWithFormat:@"%.0f",_yStepMargin * i];
        UILabel *label = [XSChartTool labelWithText:title fontSize:_axisFontSize textColor:_axisColor textAlignment:NSTextAlignmentRight];
        label.width = _leftMargin - ToAxisSpace;
        label.height = _axisLabelHeight;
        label.center = CGPointMake(_originPoint.x - _leftMargin/2 - ToAxisSpace, _originPoint.y - i*_yStepMargin);
        [self addSubview:label];
        [self.yAxisLabels addObject:label];
        [self.allSubViews addObject:label];
    }

    _yAxisLabel = [XSChartTool labelWithText:@"Y" fontSize:_axisFontSize textColor:_axisColor textAlignment:NSTextAlignmentCenter];
    [_yAxisLabel sizeToFit];
    _yAxisLabel.center = CGPointMake(_originPoint.x, _yAxisMaxValue - _yAxisLabel.height/2);
    [self addSubview:_yAxisLabel];
    [self.allSubViews addObject:_yAxisLabel];

    
    
}

- (void)drawXAxis{
    [self insertSubview:self.xScrollView atIndex:0];
    self.xScrollView.frame = CGRectMake(_originPoint.x, 0, self.width - _leftMargin, self.height);
    
    _xAxisMaxValue = _leftMargin + [[(XSChartViewModel *)self.dataSource.firstObject dataSource]count] * _xStepMargin;
    self.xScrollView.contentSize = CGSizeMake(_xAxisMaxValue + _leftMargin , 0);

    UIBezierPath *xpath = [UIBezierPath bezierPath];
    [xpath moveToPoint:CGPointMake(0, _originPoint.y)];
    [xpath addLineToPoint:CGPointMake(_xAxisMaxValue , _originPoint.y)];
    [xpath addLineToPoint:CGPointMake(_xAxisMaxValue - (_axisWidth + ToAxisSpace), _originPoint.y - ToAxisSpace)];
    [xpath moveToPoint:CGPointMake(_xAxisMaxValue , _originPoint.y)];
    [xpath addLineToPoint:CGPointMake(_xAxisMaxValue - (_axisWidth + ToAxisSpace), _originPoint.y + ToAxisSpace)];
    CAShapeLayer *xLayer = [XSChartTool shapeLayerWithPath:xpath lineWidth:_axisWidth fillColor:[UIColor clearColor] strokeColor:_axisColor];
    [self.xScrollView.layer addSublayer:xLayer];
    [self.axisLayers addObject:xLayer];

    for (int i = 0; i < self.xAxisTitles.count; i++) {
        UILabel *label = [XSChartTool labelWithText:self.xAxisTitles[i] fontSize:_axisFontSize textColor:_axisColor textAlignment:NSTextAlignmentCenter];
        [label sizeToFit];
        label.height = _axisLabelHeight;
        label.center = CGPointMake(_xStepMargin * (i+1), _originPoint.y+_axisLabelHeight/2);
        [self.xScrollView addSubview:label];
        [self.xAxisLabels addObject:label];
        [self.allSubViews addObject:label];
    }
    
    _xAxisLabel = [XSChartTool labelWithText:@"X" fontSize:_axisFontSize textColor:_axisColor textAlignment:NSTextAlignmentCenter];
    [_xAxisLabel sizeToFit];
    _xAxisLabel.center = CGPointMake(_xAxisMaxValue + ToAxisSpace, _originPoint.y);
    [self.xScrollView addSubview:_xAxisLabel];
    [self.allSubViews addObject:_xAxisLabel];

    
}
- (void)drawYAxisSeperator{
    for (int i = 1; i<self.yAxisLabels.count; i++) {
        CAShapeLayer *yLayer = nil;
        UIBezierPath *ypath = [UIBezierPath bezierPath];
        [ypath moveToPoint:CGPointMake(0, self.yAxisLabels[i].centerY)];
        if (_isShowGridding) {
            [ypath addLineToPoint:CGPointMake(_xAxisMaxValue - _leftMargin , self.yAxisLabels[i].centerY)];
            yLayer = [XSChartTool shapeLayerWithPath:ypath lineWidth:0.5 fillColor:[UIColor clearColor] strokeColor:[UIColor lightGrayColor]];
            yLayer.lineDashPattern = @[@(3),@(3)];
        }else{
            [ypath addLineToPoint:CGPointMake(5 , self.yAxisLabels[i].y)];
            yLayer = [XSChartTool shapeLayerWithPath:ypath lineWidth:_axisWidth fillColor:[UIColor clearColor] strokeColor:_axisColor];
        }
        
        [self.xScrollView.layer addSublayer:yLayer];
        [self.axisLayers addObject:yLayer];

    }
    
    
}
- (void)drawXAxisSeperator{
    for (int i = 0; i<self.xAxisLabels.count; i++) {
        CAShapeLayer *xLayer = nil;
        UIBezierPath *xpath = [UIBezierPath bezierPath];
        [xpath moveToPoint:CGPointMake(self.xAxisLabels[i].centerX , _originPoint.y)];
        if (_isShowGridding) {
            [xpath addLineToPoint:CGPointMake(self.xAxisLabels[i].centerX, self.yAxisLabels.lastObject.centerY)];
            xLayer = [XSChartTool shapeLayerWithPath:xpath lineWidth:0.5 fillColor:[UIColor clearColor] strokeColor:[UIColor lightGrayColor]];
            xLayer.lineDashPattern = @[@(3),@(3)];
        }else{
            [xpath addLineToPoint:CGPointMake(self.xAxisLabels[i].centerX, _originPoint.y - 5)];
            xLayer = [XSChartTool shapeLayerWithPath:xpath lineWidth:0.5 fillColor:[UIColor clearColor] strokeColor:[UIColor lightGrayColor]];
        }
        
        [self.xScrollView.layer addSublayer:xLayer];
        [self.axisLayers addObject:xLayer];
        
    }
    
}
#pragma mark - 点
- (void)drawChartViewPots{
    for (XSChartViewModel *model in self.dataSource) {
        if (model.plotButtons.count > 0) {
            [model.plotButtons removeAllObjects];
            [model.plotButtons makeObjectsPerformSelector:@selector(removeFromSuperview)];
        }
        for (int i = 0;i < model.dataSource.count; i++) {
            UIButton *btn = [[UIButton alloc]init];
            [btn setBackgroundImage:[XSChartTool imageFromColor:model.color rect:CGRectMake(0, 0, 1, 1)] forState:UIControlStateNormal];
            btn.size = CGSizeMake(5, 5);
            btn.layer.cornerRadius = 5/2;
            btn.layer.masksToBounds = YES;
            btn.center = CGPointMake(self.xAxisLabels[i].centerX, [self getPotYWithValue:model.dataSource[i]]);
            
            [self.xScrollView addSubview:btn];
            [self.allSubViews addObject:btn];
            [model.plotButtons addObject:btn];
            
        }
        
        
    }
    
}

#pragma mark - 折线
- (void)drawChartViewLines{
    for (XSChartViewModel *model in self.dataSource) {
        UIBezierPath *linePath = [UIBezierPath bezierPath];
        [linePath moveToPoint:CGPointMake(model.plotButtons.firstObject.centerX, model.plotButtons.firstObject.centerY)];
        for (int i = 1; i<model.plotButtons.count; i++) {
            [linePath addLineToPoint:CGPointMake(model.plotButtons[i].centerX, model.plotButtons[i].centerY)];
        }
        CAShapeLayer *lineLayer = [XSChartTool shapeLayerWithPath:linePath lineWidth:_lineWidth fillColor:[UIColor clearColor] strokeColor:model.color];
        [self.xScrollView.layer addSublayer:lineLayer];
        [self.dataLabyers addObject:lineLayer];
        
    }
    
}
- (CGFloat)getPotYWithValue:(NSString *)value{
    return  _chartViewDataHeight - value.floatValue/_dataMaxValue*_chartViewDataHeight + _topMargin ;
}

- (void)addAnimation:(BOOL)animation{
    [self.allSubViews enumerateObjectsUsingBlock:^(UIView *view , NSUInteger idx, BOOL * _Nonnull stop) {
        view.alpha = 0.0;
    }];
    [self.dataLabyers enumerateObjectsUsingBlock:^(CAShapeLayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj.hidden = YES;
    }];
    
    [self addLayerAnimation:self.axisLayers delegate:self duration:0.3];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        [self.dataLabyers enumerateObjectsUsingBlock:^(CAShapeLayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            obj.hidden = NO;
        }];
        
        [self addLayerAnimation:self.dataLabyers delegate:nil duration:0.3];
        
        [self.allSubViews enumerateObjectsUsingBlock:^(UIView *view , NSUInteger idx, BOOL * _Nonnull stop) {
            [UIView animateWithDuration:0.3 animations:^{
                view.alpha = 1.0;
            }];
        }];
    });
    
}
- (void)addLayerAnimation:(NSArray<CAShapeLayer *>*)shapeLayers delegate:(id)delegate duration:(NSTimeInterval)duration{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration = duration;
    animation.delegate = self;
    animation.fromValue = @(0);
    animation.toValue = @(1);
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    for (CAShapeLayer *layer in shapeLayers) {
        [layer addAnimation:animation forKey:nil];
    }
    
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    
}

#pragma mark - 柱状图
//多组数据
- (void)drawPillarView{
    NSInteger centerFlag = self.dataSource.count/2;
    for (int i = 0; i<self.dataSource.count; i++) {
        XSChartViewModel *model = self.dataSource[i];
        for (int j = 0; j<model.dataSource.count; j++) {
            CGFloat startX = 0;
            if (self.dataSource.count%2 == 0) {//双数
                startX = self.xAxisLabels[j].centerX + (0.5 + i - centerFlag) * _pillarWidth;
            }else{//单数个
                startX = self.xAxisLabels[j].centerX + (i - centerFlag) * _pillarWidth;
            }
            
            UIBezierPath *pillarPath = [UIBezierPath bezierPath];
            [pillarPath moveToPoint:CGPointMake(startX, _originPoint.y)];
            [pillarPath addLineToPoint:CGPointMake(startX,[self getPotYWithValue:model.dataSource[j]])];
            CAShapeLayer *pillarLayer = [XSChartTool shapeLayerWithPath:pillarPath lineWidth:_pillarWidth fillColor:model.color strokeColor:model.color];
            [self.xScrollView.layer addSublayer:pillarLayer];
            [self.dataLabyers addObject:pillarLayer];
            
        }
        
    }
    
}

#pragma mark - private method
//处理覆盖情况(坐标)
- (void)handleCoverView:(NSArray<UIView *>*)views{
    if (views.count > 1) {
        UIView *preView = views.firstObject;
        for (int i = 1; i<views.count; i++) {
            UIView *nowView = views[i];
            if (preView.right + 2 > nowView.left) {
                nowView.hidden = YES;
            }else{
                nowView.hidden = NO;
                preView = nowView;
            }
        }
        
    }
  
}


@end
